package com.yctan.base.utils;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;

/**
 * 阿里云 OSS文件类
 *
 * @ClassName AliOssCloudUtil
 * @Description TODO
 * @Author mwy
 * @Date 2020/7/30
 */
@Component
public class AliOssCloudUtil {
    //图片上传路径
    private static String endpoint;
    //图片访问路径visit
    private static String endpointVisit;
    //授权id
    private static String accessKeyId;
    //授权key
    private static String accessKeySecret;
    //空间
    private static String bucketName;

    @Value("${aly.oss.endpoint}")
    public void setEndpoint(String endpoint) {
        AliOssCloudUtil.endpoint = endpoint;
    }

    @Value("${aly.oss.endpoint.visit}")
    public void setEndpointVisit(String endpointVisit) {
        AliOssCloudUtil.endpointVisit = endpointVisit;
    }

    @Value("${aly.oss.accessKeyId}")
    public void setAccessKeyId(String accessKeyId) {
        AliOssCloudUtil.accessKeyId = accessKeyId;
    }

    @Value("${aly.oss.accessKeySecret}")
    public void setAccessKeySecret(String accessKeySecret) {
        AliOssCloudUtil.accessKeySecret = accessKeySecret;
    }

    @Value("${aly.oss.bucketName}")
    public void setBucketName(String bucketName) {
        AliOssCloudUtil.bucketName = bucketName;
    }

    public AliOssCloudUtil() {

    }


    /**
     * 上传到OSS服务器
     *
     * @param instream 文件流
     * @param fileName 文件名称 包括后缀名
     * @param filedir  文件夹路径
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public static String uploadFile2OSS(InputStream instream, String fileName, String filedir, Object... contentType) {
        OSSClient ossClient = null;
        String ret = "";
        try {
            ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            //后缀名称
            String suffix = fileName.substring(fileName.lastIndexOf(".")+1);
            //文件名称
            String prefix = fileName.substring(0,fileName.lastIndexOf("."));
            //判断文件是否存在
            int i = 1;
            while (doesObjectExist(filedir,fileName,ossClient)) {
                //如果文件存在
                fileName = prefix+"("+i+")."+suffix;
                i++;
            }
            //创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            if (contentType != null && contentType.length > 0) {
                objectMetadata.setContentType(contentType[0].toString());
            }else{
                objectMetadata.setContentType(getcontentType(suffix));
            }
            objectMetadata.setContentDisposition("inline;filename=" + fileName);

            // 指定上传文件操作时是否覆盖同名Object。
            // 不指定x-oss-forbid-overwrite时，默认覆盖同名Object。
            // 指定x-oss-forbid-overwrite为false时，表示允许覆盖同名Object。
            // 指定x-oss-forbid-overwrite为true时，表示禁止覆盖同名Object，如果同名Object已存在，程序将报错。
            objectMetadata.setHeader("x-oss-forbid-overwrite", "false");
            String objectName = filedir + fileName;
            //上传文件
            ossClient.putObject(bucketName, objectName, instream, objectMetadata);
            // 封装  url 路径
            String url = "http://" + bucketName + "." + endpointVisit + "/" + objectName;
            ret = url;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * 删除文件
     *
     * @param url 文件路径
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public static boolean delete(String url) {
        if(url==null){
            return false;
        }
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        for (int i = 0; i < 3; i++) {
            url = url.substring(url.indexOf("/") + 1);
        }
        // 删除文件。
        try {
            ossClient.deleteObject(bucketName, url);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
        return true;
    }


    /**
     * 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS，
     * 如果为true则忽略302重定向或镜像；如果为false，则考虑302重定向或镜像。
     * yourObjectName 表示上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
     *
     * @param filedir       文件夹名称
     * @param objectName    文件名称
     * @param ossClient
     * @return 存在返回true
     */
    public static boolean doesObjectExist(String filedir, String objectName, OSSClient ossClient) {
        boolean exists = ossClient.doesObjectExist(bucketName, filedir + objectName);
        return exists;
    }


    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String FilenameExtension) {
        if ("bmp".equalsIgnoreCase(FilenameExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(FilenameExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(FilenameExtension) ||
                "jpg".equalsIgnoreCase(FilenameExtension) ||
                "png".equalsIgnoreCase(FilenameExtension)) {
            return "image/jpeg";
        }
        if ("html".equalsIgnoreCase(FilenameExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(FilenameExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.visio";
        }
        if ("pptx".equalsIgnoreCase(FilenameExtension) ||
                "ppt".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("docx".equalsIgnoreCase(FilenameExtension) ||
                "doc".equalsIgnoreCase(FilenameExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(FilenameExtension)) {
            return "text/xml";
        }
        return "image/jpeg";
    }


}